<template>
  <div>
    <!--  展示视图===========================  -->
    <template v-if="enableQueryData">
      <div class="view-item" ref="point"
           :style="{
              cursor: 'pointer',
              left: val.x+'px',
              top: val.y+'px',
              width: val.w+'px',
              height: val.h+'px',
              zIndex: val.z
              }">
        <div class="device-point" :class="{'alarm': isAlarm}" @click="goDeviceView">
          <div v-if="isAlarm" class="alarm-animation"></div>
        </div>
      </div>

      <div class="view-item" ref="label"
           :style="{
              left: val.label.x+'px',
              top: val.label.y+'px',
              width: val.label.w+'px',
              zIndex: val.z
              }">
        <el-popover popper-class="device-data-popover"
                    placement="right"
                    trigger="hover">
          <ul v-if="deviceData && deviceData.length>0" class="device-data-list">
            <li v-for="item in deviceData">
              <label>{{item.name}}</label>
              <span>{{item.value}}{{item.unit}}</span>
            </li>
          </ul>
          <div v-else>无数据</div>

          <div slot="reference" class="device-label" style="border: 1px solid #aaa"
               :style="{
           width: val.label.w + 'px'
           }">
            {{device.name || val.deviceName}}
          </div>
        </el-popover>

      </div>
    </template>
    <!--  组态编辑视图===========================  -->
    <template v-else>
      <!--  定位点  -->
      <vue-draggable-resizable ref="point" style="position: absolute"
                               :style="{zIndex:val.z}"
                               :active="active"
                               :draggable="!disabled"
                               :resizable="false"
                               :prevent-deactivation="false"
                               :x="val.x"
                               :y="val.y"
                               :w="val.w"
                               :h="val.h"
                               :scale="zoom/100"
                               @dragging="onItemDrag"
                               @mousedown.native="onItemActivated(val)"

      >
        <div class="device-point"></div>
      </vue-draggable-resizable>

      <!--  设备标签  -->
      <vue-draggable-resizable ref="label" style="position: absolute"
                               :style="{zIndex:val.z}"
                               :draggable="!disabled"
                               :resizable="false"
                               :prevent-deactivation="false"
                               :x="val.label.x"
                               :y="val.label.y"
                               :w="val.label.w"
                               :h="val.label.h"
                               :scale="zoom/100"
                               @dragging="onLabelDrag"

      >
        <div class="device-label" style="border: 1px solid #aaa"
             :style="{
           width: val.label.w + 'px'
           }">
          {{device.name || val.deviceName}}
        </div>
      </vue-draggable-resizable>
    </template>

    <!-- svg连接线   -->
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1"
         :style="{
              position: 'absolute',
              width: svgLineData.w+'px',
              height: svgLineData.h+'px',
              left: svgLineData.x+'px',
              top: svgLineData.y+'px',
           }">
      <polyline :points="svgLineData.points"
                :style="svgLineData.style"/>
    </svg>
  </div>

</template>
<script>
  import StylePane from './style.vue';
  import dataMixin from '../mixins/data';
  //可拖拽
  import VueDraggableResizable from 'vue-draggable-resizable';
  // optionally import default styles
  import 'vue-draggable-resizable/dist/VueDraggableResizable.css';
  import {getDevice} from '@/api/device/device';
  import {listData} from '@/api/biz/deviceData';
  import {listAlarm} from '@/api/biz/alarm';
  import {getByBizId} from "@/api/iot/view";
  import {listFuncByDeviceCode} from '@/api/biz/productFunc';

  import svgLine from './svg-line';

  const NAME = 'vpd-device2';
  const setting = {
    complex: true,
    type: NAME,
    dataType: 'text',
    resizeable: false,
    x: 0,
    y: 0,
    w: 20,
    h: 20,
    minWidth: 20,
    minHeight: 20,
    fontSize: 14,
    backgroundColor: null,
    borderWidth: 1,
    borderColor: '#aaa',

    fit: 'contain', //确定图片如何适应到容器框，同原生 object-fit
    deviceId: null,
    deviceName: '设备',
    label: {
      x: 200,
      y: 200,
      w: 200,
      h: 50,
    },
  };
  export default {
    mixins: [dataMixin],
    name: NAME,
    icon: 'vpd-device',
    title: '设备标签',
    panel: StylePane,
    setting: setting,
    components: {
      VueDraggableResizable
    },
    props: {
      val: {
        type: Object
      },
      active: {
        type: Boolean,
        default: false
      },
      disabled: {
        type: Boolean,
        default: false
      },
      zoom: {
        type: Number,
        default: 100
      },
      pageInfo: {
        type: Object
      },
    },
    data() {
      return {
        deviceAttrMap: {},
        setting: JSON.parse(JSON.stringify(setting)),
        device: {}, //设备信息
        deviceData: [], //设备数据
        alarmList: [], //设备告警
        line: null,
        timer: null,
      }
    },
    computed: {
      svgLineData() {
        const a = {
          x: this.val.x,
          y: this.val.y,
          w: this.val.w,
          h: this.val.h,
        };
        const b = {
          x: this.val.label.x,
          y: this.val.label.y,
          w: this.val.label.w,
          h: this.val.label.h,
        };
        const line = svgLine(a, b);
        // console.log('======line', line);
        return line;
      },
      isAlarm() {
        return this.alarmList && this.alarmList.length > 0
      },
      label() {
        return this.device.name || this.val.deviceName;
      },
    },
    watch: {},
    mounted() {

      if (this.enableQueryData) {
        this.getData();

        this.timer = setInterval(() => {
          this.getData();
        }, 30 * 1000)
      }
    },
    beforeDestroy() {
      clearInterval(this.timer);
    },
    methods: {
      getData() {
        const deviceId = this.val.deviceId;
        const deviceCode = this.val.deviceCode;
        if (!deviceId) {
          return;
        }
        //获取设备信息
        getDevice(deviceId).then(res => {
          this.device = res.data;
        });
        //查询设备所属产品的属性
        listFuncByDeviceCode(deviceCode).then(res => {
          this.deviceAttrMap = res.data.reduce((prev, item) => {
            prev[item.code] = item;
            return prev;
          }, {});

          //获取设备数据
          return listData({deviceCode: deviceCode});
        }).then(res => {
          //处理后的数据，代码转名称，单位等
          this.deviceData = this.processDeviceData(res.rows);
        });


        //获取设备告警
        listAlarm({
          deviceId: deviceId
        }).then(res => {
          this.alarmList = res.rows;
        })

      },

      processDeviceData(deviceData) {
        const attrMap = this.deviceAttrMap;
        deviceData.forEach(item => {
          const attr = attrMap[item.signalCode];
          if (attr) {
            //属性的数据定义
            const def = attr.dataDef ? JSON.parse(attr.dataDef) : {};
            let val = item.value;
            //布尔类型和枚举类型，需要代码转名称
            if (attr.dataType === 'bool' || 'enum' && def[val]) {
              val = def[val];
            }
            //如果有单位，加上单位
            if (def.unit) {
              val += def.unit;
            }
            item.value = val;
          }
        });
        return deviceData;
      },

      onItemDrag(left, top) {
        this.val.x = left;
        this.val.y = top;
      },
      onLabelDrag(left, top) {
        this.val.label.x = left;
        this.val.label.y = top;
      },

      onItemActivated(item) {
        this.$emit('activated');
      },
      showOperList(ev, item) {
        this.$emit('contextmenu', ev, item);
      },
      updateData(data) {
        console.log('=====================')
      },
      goDeviceView() {

        const device = this.device;
        //获取设备配置的页面
        getByBizId('product', device.productId).then(res => {
          if (res.code === 200) {
            const view = res.data;
            this.$router.push({
              name: 'DeviceMonitor',
              query: {
                id: view.id,
                deviceCode: device.code,
                deviceId: device.id,
                productId: device.productId
              }
            });
          } else {
            this.msgError(res.msg);
          }
        })
      },
    }
  }
</script>
<style lang="scss">
  .device-data-popover {
    background-color: rgba(30, 130, 250, 0.8);
    color: #fff;
  }
</style>
<style lang="scss" scoped>
  .view-item {
    position: absolute;
  }

  .vdr {
    /*不显示边框*/
    border: none;
  }

  .device-point {
    width: 20px;
    height: 20px;
    background-color: rgba(30, 130, 250, 1);
    border-radius: 20px
  }

  .device-point.alarm {
    background-color: red;
  }

  .device-label {
    color: #fff;
    background-color: rgba(30, 130, 250, 0.8);
    border: 1px solid #e6f7ff;
    padding: 5px 10px;
    word-break: break-all;
    min-height: 50px;
    font-size: 16px;
  }

  ul.device-data-list {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 600px;
    overflow-y: auto;

    li {
      padding: 0;
      margin: 0;
      list-style: none;

      label {
        display: inline-block;
        min-width: 60px;
      }
    }
  }

  .device-name {
    height: 30px;
    font-size: 14px;
    line-height: 30px;
    text-align: center;
    background-color: #fff;
    overflow: hidden;
  }

  .alarm-animation {
    position: absolute;
    left: -10px;
    top: -10px;
    height: 40px;
    width: 40px;
    border-radius: 25px;
    background: rgba(255, 0, 0, 0.9);

    opacity: .9;
    transform: scale(0);
    animation: alarm 1.5s;
    animation-iteration-count: infinite;
  }

  @keyframes alarm {
    0% {
      transform: scale(0.5);
      opacity: 0.8;
    }

    30% {
      opacity: 0.5;
    }

    100% {
      transform: scale(1.5);
      opacity: 0;
    }
  }


</style>
